package com.cyanite.playlv2;

import com.cyanite.playlv2.interpolator.ExpoInterpolator;
import com.cyanite.playlv2.interpolator.EasingType.Type;
import com.cyanite.playlv2.util.NotificationsUtil;
import com.cyanite.playlv2.util.RemoteResourceManager;
import com.cyanite.playlv2.widget.Panel;
import com.cyanite.playlv2.widget.TipsListAdapter;
import com.cyanite.playlv2.widget.Panel.OnPanelListener;
import com.cyanite.playlv2api.types.Tip;
import com.cyanite.playlv2api.types.Group;
import com.cyanite.playlv2api.types.Response;
import com.cyanite.playlv2api.types.Task;
import com.cyanite.playlv2api.util.ConstantsUtils.TipCategoryConsts;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.util.Observable;
import java.util.Observer;

public class AddTipsActivity extends Activity {

    public static final String EXTRA_TASK_PARCEL = PlayLv2.PACKAGE_NAME
        + ".TipsActivity.EXTRA_TASK_PARCEL";

    private StateHolder mStateHolder;
    private ProgressDialog mProgressDialog;
    private View mViewProgressBar;
    private Handler mHandler;
    private RemoteResourceManager mRrm;
    private RemoteResourceManagerObserver mResourcesObserver;
    private Panel mPanel;
    private LinearLayout mllSecond;
    private EditText mTipText;
    private LinearLayout mEmpty;
    
    private BroadcastReceiver mLoggedOutReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            finish();
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState)    {
        super.onCreate(savedInstanceState);
        registerReceiver(mLoggedOutReceiver, new IntentFilter(PlayLv2.INTENT_ACTION_LOGGED_OUT));
        setContentView(R.layout.add_tips_activity);

        mStateHolder = new StateHolder();
        if (getIntent().hasExtra(EXTRA_TASK_PARCEL))    {
            mStateHolder.setTask((Task)getIntent().getExtras().getParcelable(EXTRA_TASK_PARCEL));
        }   else {
            finish();
            return;
        }
        mHandler = new Handler();
        mRrm = ((PlayLv2) getApplication()).getRemoteResourceManager();
        mResourcesObserver = new RemoteResourceManagerObserver();
        mRrm.addObserver(mResourcesObserver);

        mViewProgressBar = findViewById(R.id.tipsHistoryProgress);
        mViewProgressBar.setVisibility(View.VISIBLE);
        mStateHolder.startTaskTipsHistory(this);
        ensureUi();
    }

    private void ensureUi() {
        setTitle(getString(R.string.add_tips_activity_label));

        ensureTaskPhoto(mStateHolder.getTask().getPhoto());
        mllSecond = (LinearLayout)findViewById(R.id.llSecondlayer);
        mllSecond.getBackground().setAlpha(0);
        mEmpty = (LinearLayout) findViewById(R.id.llEmptyTips);
        mTipText = (EditText)findViewById(R.id.etCommonInfo);
        Button btnTip = (Button)findViewById(R.id.btnUserTip);
        btnTip.setOnClickListener(new Button.OnClickListener()  {
            public void onClick(View v)  {
                mStateHolder.startTaskAddTip(AddTipsActivity.this, mTipText.getText().toString());
            }
        });

        mPanel = (Panel)findViewById(R.id.bottomPanel);
        mPanel.setInterpolator(new ExpoInterpolator(Type.OUT));
        mPanel.setOnPanelListener(new OnPanelListener(){
             public void onPanelClosed(Panel panel) {
                 mllSecond.getBackground().setAlpha(0);
                 mStateHolder.setIsPanelOpen(false);
                 mTipText.setText("");
             }
             public void onPanelOpened(Panel panel) {
                 mllSecond.getBackground().setAlpha(170);
                 mStateHolder.setIsPanelOpen(true);
             }
         });

        TextView name = (TextView)findViewById(R.id.tvUserName);
        name.setText(mStateHolder.getTask().getUserName());

        TextView info = (TextView)findViewById(R.id.tvLineInfo);
        info.setText(mStateHolder.getTask().getInfo().getInfo1());

        Button btnTripDetail = (Button)findViewById(R.id.btnTripDetail);

        if ( mStateHolder.getTask() != null && mStateHolder.getTask().getTripId() != null)   {
            btnTripDetail.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (mStateHolder.getTask().getTripId() != null) {
                        Intent intent = new Intent(AddTipsActivity.this, TripDetailsActivity.class);
                        intent.putExtra(TripDetailsActivity.EXTRA_TRIP_ID, mStateHolder.getTask().getTripId());
                        startActivity(intent);
                    }
                }
            });
        }   else {
            btnTripDetail.setVisibility(View.GONE);
        }

        updateUi();
    }

    private void updateUi() {
        if ( mStateHolder.getTips() != null && mStateHolder.getTips().size() > 0 )   {
            mEmpty.setVisibility(View.GONE);
            ListView listTips = (ListView)findViewById(R.id.lvUserTip);
            TipsListAdapter listAdapter = new TipsListAdapter(this, ((PlayLv2) getApplication()).getRemoteResourceManager(), R.layout.tip_list_item);
            listAdapter.setGroup(mStateHolder.getTips());
            listTips.setAdapter(listAdapter);
        }
    }

    private void ensureTaskPhoto(String photo) {
        ImageView ivPhoto = (ImageView)findViewById(R.id.imgUserPhoto);
        ivPhoto.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(AddTipsActivity.this, UserDetailsActivity.class);
                intent.putExtra(UserDetailsActivity.EXTRA_USER_ID, mStateHolder.getTask().getUserId());
                startActivity(intent);
            }
        });

        if (photo == null) {
            ivPhoto.setImageResource(R.drawable.blank_girl);
            return;
        }

        Uri uriPhoto = Uri.parse(photo);
        if (mRrm.exists(uriPhoto)) {
            try {
                Bitmap bitmap = BitmapFactory.decodeStream(mRrm.getInputStream(uriPhoto));
                ivPhoto.setImageBitmap(bitmap);
            } catch (IOException ex) {
                ivPhoto.setImageResource(R.drawable.blank_girl);
            }
        } else {
            mRrm.request(uriPhoto);
            ivPhoto.setImageResource(R.drawable.blank_girl);
        }

        ivPhoto.postInvalidate();
        ivPhoto.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
           if (mStateHolder.getIsPanelOpen()) {
               mPanel.setOpen(false, true);
           }    else {
               finish();
           }
           return true;
        }
        else
            return super.onKeyDown(keyCode, event);
    }

    @Override
    public void onPause() {
        super.onPause();
        if (isFinishing()) {
            mStateHolder.cancelTasks();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(mLoggedOutReceiver);
    }

    private void onTipsHistoryTaskComplete(Group<Tip> tips, Exception ex) {
        mViewProgressBar.setVisibility(View.GONE);
        if ( tips != null && tips.size() > 0 ) {
            mStateHolder.setTips(tips);            
        } else {
            mEmpty.setVisibility(View.VISIBLE);
        }
        updateUi();
    }

    private static class TipsHistoryTask extends AsyncTask<Void, Void, Group<Tip>> {

        private AddTipsActivity mActivity;
        private String mTaskId;
        private Exception mReason;

        public TipsHistoryTask(AddTipsActivity activity, String taskId) {
            mActivity = activity;
            mTaskId = taskId;
        }

        @Override
        protected void onPreExecute() {
        }

        @Override
        protected Group<Tip> doInBackground(Void... params) {
            try {
                return ((PlayLv2) mActivity.getApplication()).getPlayLv2Api().tips(mTaskId);
            } catch (Exception ex) {
                mReason = ex;
                return null;
            }
        }

        @Override
        protected void onPostExecute(Group<Tip> tips) {
            if (mActivity != null) {
                mActivity.onTipsHistoryTaskComplete(tips, mReason);
            }
        }
    }

    private void onAddTipsTaskComplete(Response response, Exception ex) {
        dismissProgressDialog();
        if (response != null && response.getValue().equals("0")) {
            Toast.makeText(this,
                    getResources().getString(R.string.add_tips_activity_add_ok),
                    Toast.LENGTH_LONG).show();
            if (mStateHolder.getIsPanelOpen()) {
                mPanel.setOpen(false, true);
            }
            mStateHolder.startTaskTipsHistory(AddTipsActivity.this);
        } else {
            NotificationsUtil.ToastReasonForFailure(this, ex);
        }
    }

    private static class AddTipTask extends AsyncTask<Void, Void, Response> {

        private AddTipsActivity mActivity;
        private String mUserId;
        private String mCategoryId;
        private String mContent;
        private int mCategoryType;
        private Exception mReason;

        public AddTipTask(AddTipsActivity activity, String userId, String categoryId,
                String content, int categoryType) {
            mActivity = activity;
            mUserId = userId;
            mCategoryId = categoryId;
            mContent = content;
            mCategoryType = categoryType;
        }

        @Override
        protected void onPreExecute() {
            mActivity.showProgressDialog();
        }

        @Override
        protected Response doInBackground(Void... params) {
            try {
                Response response = null;
                response = ((PlayLv2) mActivity.getApplication()).getPlayLv2Api().addTip(mUserId, mCategoryId, mContent, mCategoryType);
                if (response == null) response = new Response();
                return response;
            } catch (Exception ex) {
                mReason = ex;
                return null;
            }
        }

        @Override
        protected void onPostExecute(Response response) {
            if (mActivity != null) {
                mActivity.onAddTipsTaskComplete(response, mReason);
            }
        }

        public void setActivity(AddTipsActivity activity) {
            mActivity = activity;
        }

        @Override
        protected void onCancelled() {
            mActivity.dismissProgressDialog();
        }
    }

    private ProgressDialog showProgressDialog() {
        if (mProgressDialog == null) {
            ProgressDialog dialog = new ProgressDialog(this);
            dialog.setMessage(getString(R.string.add_tips_activity_add_progress));
            dialog.setIndeterminate(true);
            dialog.setCancelable(true);
            mProgressDialog = dialog;
        }
        mProgressDialog.show();
        return mProgressDialog;
    }

    private void dismissProgressDialog() {
        try {
            mProgressDialog.dismiss();
        } catch (IllegalArgumentException e) {
            // We don't mind. android cleared it for us.
        }
    }

    private class RemoteResourceManagerObserver implements Observer {
        @Override
        public void update(Observable observable, Object data) {
            mHandler.post(mRunnableUpdateUserPhoto);
        }
    }

    private Runnable mRunnableUpdateUserPhoto = new Runnable() {
        @Override
        public void run() {
            ensureTaskPhoto(mStateHolder.getTask().getPhoto());
        }
    };

    private static class StateHolder {

        private Task mTask;
        private Group<Tip> mTips;
        private AddTipTask mTaskAddTip;
        private TipsHistoryTask mTaskTipsHistory;
        private boolean mIsPanelOpen;

        public StateHolder() {
            mIsPanelOpen = false;
        }

        public boolean getIsPanelOpen() {
            return mIsPanelOpen;
        }

        public void setIsPanelOpen(boolean isOpen) {
            mIsPanelOpen = isOpen;
        }

        public Task getTask()   {
            return mTask;
        }

        public void setTask(Task task)  {
            mTask = task;
        }

        public Group<Tip> getTips() {
            return mTips;
        }

        public void setTips(Group<Tip> tips)    {
            mTips = tips;
        }

        public void startTaskTipsHistory(AddTipsActivity activity) {
            mTaskTipsHistory = new TipsHistoryTask(activity, mTask.getId());
            mTaskTipsHistory.execute();
        }

        public void startTaskAddTip(AddTipsActivity activity, String content) {
            mTaskAddTip = new AddTipTask(activity, mTask.getUserId(), mTask.getId(), content, TipCategoryConsts.TIP_CATEGORY_TASK);
            mTaskAddTip.execute();
        }

        public void cancelTasks() {
            if (mTaskAddTip != null) {
                mTaskAddTip.setActivity(null);
                mTaskAddTip.cancel(true);
            }
        }
    }
}
